package cn.iune.erp.inventory;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;

import cn.iune.erp.setting.ISettingService;


@Transactional
@Service
public class FileItemServiceImpl implements IFileItemService {
	
	private final Logger log = LogManager.getLogger(this);

	@Autowired
	private IFileItemDao dao;
	@Autowired
	private IStorageItemDao detailDao;
	
	@Autowired
	private ISettingService settingService;
	

	@Transactional
	@Override
	public void insert(FileItem obj) {
		dao.insert(obj);
	}

	@Transactional
	@Override
	public void delete(String fID) {
		dao.delete(fID);
	}
	
	/*
	@Transactional
	@Override
	public void delete(String fID, String userId) {
		dao.delete(fID, userId);
	}
	*/

	@Transactional
	@Override
	public void update(FileItem obj) {
		dao.update(obj);
	}
	
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#getAll()
	 */
	@Override
	public List<FileItem> getAll(){
		return dao.getAll();
	}
	
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#getByID(java.lang.String)
	 */
	@Override
	public FileItem getByID(String fID) {
		return dao.getByID(fID);
	}


	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#getByNo(java.lang.String, java.lang.String)
	 */
	@Override
	public FileItem getByNo(String itemNo, String enterpriseNo) {
		return dao.getByNo(itemNo, enterpriseNo);
	}
	
	@Override
	public FileItem getByProperty(String groupID, String itemProperty) {
		return dao.getByProperty(groupID, itemProperty);
	}
	
	@Override
	public FileItem getByBarcode(String barcode, String enterpriseNo) {
		return dao.getByBarcode(barcode, enterpriseNo);
	}

	
	@Override
	public List<FileItem> getSKUList(String fID) {
		return dao.getSKUList(fID);
	}
	
	@Override
	public List<FileItem> getList(String enterpriseNo){
		return dao.getList(enterpriseNo);
	}
	
	//获取产品（成品、半成品、自制件、委外件、虚拟件）列表，不包含采购件，按低阶码倒排序
	@Override
	public List<FileItem> getProductList(String enterpriseNo) {
		return dao.getProductList(enterpriseNo);
	}
	
	@Override
	public List<FileItem> getListByLevelCode(String levelCode, String enterpriseNo) {
		return  dao.getListByLevelCode(levelCode, enterpriseNo);
	}
	
	@Override
	public List<FileItem> filterByNo(String likeNo, String enterpriseNo) {
		return dao.filterByNo(likeNo, enterpriseNo);
	}
	
	@Transactional
	@Override
	public void deleteSKU(String fParent) {
		dao.deleteSKU(fParent);
	}
	
	
	//零售专用
	//获取商品列表（不包含SKU级别，只包含顶级物料档案列表）
	@Override
	public JSONObject querySimple(JSONObject param, String ossServer){
		
		JSONObject json = new JSONObject();
		JSONObject data;
		try {
			data = dao.querySimple(param);
		} catch (SQLException e) {
			e.printStackTrace();
			
			json.put("code", -1);
			json.put("status", e.getMessage());
			json.put("msg", "failure");
			
			return json;
		}
		//开始装配
		
		JSONArray arrayItem = new JSONArray();
		
		JSONArray rows = data.getJSONArray("data");
		
		for(int i =0;i<rows.size();i++) {
			
			//转换成JSON
			JSONObject rowObject = rows.getJSONObject(i);
			//装配图片
			//String itemName = rowObject.getString("itemName");
			//log.info("querySimple.itemName-->>"+itemName);
			String imageurl = rowObject.getString("imageurl");
			//log.info("querySimple.imageurl-->>"+imageurl);
			JSONArray arrayImageurl = new JSONArray();
			if(imageurl!=null) {
				//单图
				//http://www.iune.cn/group1/M00/00/00/cxzWEVq2MjCAc8JsAAAuxlb_9jI617.jpg
				arrayImageurl = JSONArray.parseArray(imageurl);
				//[{"remoteFileName":"M00/00/01/cxzWEVuxsaGAGM53AABkeWyTCEw855.jpg","groupName":"group1","originalFilename":"131097612878657419_wmk.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZ24yAMd2MAACxW7HAcco856.jpg","groupName":"group1","originalFilename":"589d3de5N48cfbe46.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZVsKAEKl3AAAcaGOOVFo105.jpg","groupName":"group1","originalFilename":"ljdxm.jpg"},{"remoteFileName":"M00/00/00/cxzWEVtVQp-AMgkoAAAVTb55arQ384.png","groupName":"group1","originalFilename":"Untitled.png"}]
				//log.info(arrayImageurl.toJSONString());
				JSONObject jsonObject = arrayImageurl.getJSONObject(0);
				String groupName = jsonObject.getString("groupName");
				String remoteFileName = jsonObject.getString("remoteFileName");
				String url = ossServer + "/" + groupName + "/" + remoteFileName;
				//封面（单图）
				rowObject.put("pic", url);
			}else {
				//rowObject.put("pic", "assets/img/zwtp.jpg");
			}

			/*			
			JSONArray pics = new JSONArray();
			String images = fileItem.getImages();
			JSONArray arrayImages = new JSONArray();
			if(images!=null) {
				//图集（多图片）
				//http://www.iune.cn/group1/M00/00/00/cxzWEVq2MjCAc8JsAAAuxlb_9jI617.jpg
				String ossServer = appConfigParams.getOssServer();//"http://www.iune.cn";
				arrayImages = JSONArray.parseArray(images);
				//[{"remoteFileName":"M00/00/01/cxzWEVuxsaGAGM53AABkeWyTCEw855.jpg","groupName":"group1","originalFilename":"131097612878657419_wmk.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZ24yAMd2MAACxW7HAcco856.jpg","groupName":"group1","originalFilename":"589d3de5N48cfbe46.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZVsKAEKl3AAAcaGOOVFo105.jpg","groupName":"group1","originalFilename":"ljdxm.jpg"},{"remoteFileName":"M00/00/00/cxzWEVtVQp-AMgkoAAAVTb55arQ384.png","groupName":"group1","originalFilename":"Untitled.png"}]
				log.info(arrayImages.toJSONString());
				for(Object obj : arrayImages) {
					JSONObject jsonObject = (JSONObject) obj;
					String groupName = jsonObject.getString("groupName");
					String remoteFileName = jsonObject.getString("remoteFileName");
					String url = ossServer + "/" + groupName + "/" + remoteFileName;

					JSONObject jsonPic = new JSONObject();
					jsonPic.put("goodsId", fileItem.getfID());
					jsonPic.put("pic", url);
					pics.add(jsonPic);
				}
			}
			row.put("pics", pics);
			*/
			BigDecimal minPrice = rowObject.getBigDecimal("salePrice");
			BigDecimal maxPrice = rowObject.getBigDecimal("salePrice");
		
			//设置最低售价和最高售价
			rowObject.put("minPrice", minPrice);
			rowObject.put("maxPrice", maxPrice);
			
			arrayItem.add(rowObject);
		}
		
		json.put("data", arrayItem);
		json.put("code", 0);
		json.put("msg", "success");
		json.put("total", data.getBigInteger("total"));

		return json;
	}

	/*
	public JSONObject query(JSONObject data) throws Throwable {
		
		// 获取参数
		Object columns = data.getJSONObject("columns"); // 列定义
		Integer limit = data.getInteger("limit"); // 分页查询的行数
		Integer offset = data.getInteger("offset"); // 分页查询的行偏移
		String search = data.getString("search"); // 检索关键字
		String filter = data.getString("filter"); // 过滤条件
		String id = data.getString("id");

		
		// 存放SQL中的参数值
		List<Object> sqlParams = new ArrayList<Object>();
		// 存放SQL中的过滤条件
		List<String> filters = new ArrayList<String>();
		if (!CommonService.isEmptyString(search)) {
			// 增加过滤条件
			filters.add("itemNo LIKE ? OR itemName LIKE ? OR rationSize LIKE ?");
			// 检索关键字中如果没有%，则前后自动加%
			search = (search.indexOf("%") != -1) ? search : "%" + search + "%";
			// sqlParams的参数个数和顺序必须与过滤条件的?相匹配 
			for (int i = 0; i < 3; i++) {
				sqlParams.add(search);
			}
		}
		//处理过滤条件
		if (!CommonService.isEmptyString(filter)) {
			filters.add(filter);
		}
		//处理id
		if (!CommonService.isEmptyString(id)) {
			filters.add("fID='"+id+"'");
		}
	
		
		Table table = Transform.createTableByColumnsDefine((JSONObject) columns);
		
		if (offset != null && offset.equals(0)) {
			long rowCount = dao.getCount(filters, sqlParams);
			table.setTotal((int)rowCount);
		}

		String orderBy = "cDatetime DESC";
				
		//获取数据
		List<Row> rows = listToRows(dao.query(filters,orderBy,sqlParams,offset,limit));
	    table.appendRows(rows);
		JSONObject json = Transform.tableToJson(table);
	
		return json;
	}


	public int save(JSONObject object) throws Throwable {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		List<FileItem> list = rowsToList(table.getRows());
		for(FileItem obj : list){
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				dao.update(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
			}
		}
		return 0;
	}

	public List<Row> listToRows(List<FileItem> list){
		//添加行集
		List<Row> rows = new ArrayList<Row>();
		//循环行
	    for(FileItem o : list){
	    	rows.add(objectToRow(o));
	    }
	    return rows;
	}

	public List<FileItem> rowsToList(List<Row> rows){
		//添加行集
		List<FileItem> list = new ArrayList<FileItem>();
		//循环行
	    for(Row r : rows){
	    	list.add(rowToObject(r));
	    }
	    return list;
	}

	public Row objectToRow(FileItem o){
    	
		Map<String, ColumnValue> values = new HashMap<String, ColumnValue>();
		//循环行中每一列
		Object value = null;
		value = o.getfID();
		values.put("fID", new ColumnValue(value));
		
		value = o.getSystemCode();
 		values.put("systemCode", new ColumnValue(value));
		value = o.getBillType();
 		values.put("billType", new ColumnValue(value));
		value = o.getBillTypeName();
 		values.put("billTypeName", new ColumnValue(value));
		value = o.getOrderDate();
 		values.put("orderDate", new ColumnValue(value));
		value = o.getState();
 		values.put("state", new ColumnValue(value));
		value = o.getStatus();
 		values.put("status", new ColumnValue(value));
 		
		value = o.getGroupID();
 		values.put("groupID", new ColumnValue(value));
		value = o.getGroupCode();
 		values.put("groupCode", new ColumnValue(value));
		value = o.getGroupName();
 		values.put("groupName", new ColumnValue(value));
		value = o.getGroupFullName();
 		values.put("groupFullName", new ColumnValue(value));
 		
		value = o.getItemNo();
 		values.put("itemNo", new ColumnValue(value));
		value = o.getRationSize();
 		values.put("rationSize", new ColumnValue(value));
		value = o.getItemName();
 		values.put("itemName", new ColumnValue(value));

		value = o.getClassCode();
 		values.put("classCode", new ColumnValue(value));
		value = o.getClassLabel();
 		values.put("classLabel", new ColumnValue(value));
		value = o.getItemProperty();
 		values.put("itemProperty", new ColumnValue(value));
		value = o.getOrgID();
 		values.put("orgID", new ColumnValue(value));
		value = o.getOrgFName();
 		values.put("orgFName", new ColumnValue(value));

		value = o.getUnitCode();
 		values.put("unitCode", new ColumnValue(value));
		value = o.getUnitName();
 		values.put("unitName", new ColumnValue(value));
		value = o.getProcess();
 		values.put("process", new ColumnValue(value));
		value = o.getProcessLabel();
 		values.put("processLabel", new ColumnValue(value));
		value = o.getCostingType();
 		values.put("costingType", new ColumnValue(value));
		value = o.getQualityType();
 		values.put("qualityType", new ColumnValue(value));
		value = o.getQualityTypeLabel();
 		values.put("qualityTypeLabel", new ColumnValue(value));
		value = o.getQualityPeriod();
 		values.put("qualityPeriod", new ColumnValue(value));

		value = o.getStoreNo();
 		values.put("storeNo", new ColumnValue(value));
		value = o.getBatchNo();
 		values.put("batchNo", new ColumnValue(value));
		value = o.getPlanType();
 		values.put("planType", new ColumnValue(value));
 		
		value = o.getForSale();
 		values.put("forSale", new ColumnValue(value));
		value = o.getForUsed();
 		values.put("forUsed", new ColumnValue(value));
		value = o.getImages();
 		values.put("images", new ColumnValue(value));
		
		value = o.getItemWeight();
 		values.put("itemWeight", new ColumnValue(value));
		value = o.getItemSize();
 		values.put("itemSize", new ColumnValue(value));
 		
		value = o.getStorageNo();
 		values.put("storageNo", new ColumnValue(value));
		value = o.getStorageName();
 		values.put("storageName", new ColumnValue(value));
		value = o.getStorageType();
 		values.put("storageType", new ColumnValue(value));
		value = o.getStorageTypeLabel();
 		values.put("storageTypeLabel", new ColumnValue(value));
		value = o.getFloorNo();
 		values.put("floorNo", new ColumnValue(value));

		value = o.getTaxType();
 		values.put("taxType", new ColumnValue(value));
		value = o.getTaxTypeLabel();
 		values.put("taxTypeLabel", new ColumnValue(value));
		value = o.getTaxRate();
 		values.put("taxRate", new ColumnValue(value));
		value = o.getItemPrice();
 		values.put("itemPrice", new ColumnValue(value));
 		
		value = o.getSaxType();
 		values.put("saxType", new ColumnValue(value));
		value = o.getSaxTypeLabel();
 		values.put("saxTypeLabel", new ColumnValue(value));
		value = o.getSaxRate();
 		values.put("saxRate", new ColumnValue(value));
		value = o.getSalePrice();
 		values.put("salePrice", new ColumnValue(value));
		
		value = o.getAbcGrade();
 		values.put("abcGrade", new ColumnValue(value));
 		
		value = o.getProviderNo();
 		values.put("providerNo", new ColumnValue(value));
		value = o.getShortName();
 		values.put("shortName", new ColumnValue(value));
		value = o.getProviderName();
 		values.put("providerName", new ColumnValue(value));
		value = o.getWorkcenterNo();
 		values.put("workcenterNo", new ColumnValue(value));
		value = o.getWorkcenterName();
 		values.put("workcenterName", new ColumnValue(value));
		value = o.getWorkcenterLName();
 		values.put("workcenterLName", new ColumnValue(value));
		
		value = o.getHumanHour();
 		values.put("workingHourPlan", new ColumnValue(value));
		value = o.getMachineHour();
 		values.put("machineHourPlan", new ColumnValue(value));
		value = o.getRoutingNo();
 		values.put("routingNo", new ColumnValue(value));
		value = o.getRoutingItemNo();
 		values.put("routingItemNo", new ColumnValue(value));
 		
		value = o.getLevelCode();
 		values.put("levelCode", new ColumnValue(value));
 		
		value = o.getMaterialAmountPer();
 		values.put("materialAmountPer", new ColumnValue(value));
		value = o.getHumanAmountPer();
 		values.put("workingAmountPer", new ColumnValue(value));
		value = o.getManufactAmountPer();
 		values.put("manufactAmountPer", new ColumnValue(value));
		value = o.getProcessAmountPer();
 		values.put("processAmountPer", new ColumnValue(value));
		value = o.getCostingAmountPer();
 		values.put("costingAmountPer", new ColumnValue(value));
		
		value = o.getMaterialAmount();
 		values.put("materialAmount", new ColumnValue(value));
		value = o.getHumanAmount();
 		values.put("workingAmount", new ColumnValue(value));
		value = o.getManufactAmount();
 		values.put("manufactAmount", new ColumnValue(value));
		value = o.getProcessAmount();
 		values.put("processAmount", new ColumnValue(value));
		value = o.getCostingAmount();
 		values.put("costingAmount", new ColumnValue(value));
		
		value = o.getValidDays();
 		values.put("validDays", new ColumnValue(value));
		value = o.getCheckoutAgainDays();
 		values.put("checkoutAgainDays", new ColumnValue(value));
		value = o.getHumanPrice();
 		values.put("humanPrice", new ColumnValue(value));
		value = o.getQuantityL();
 		values.put("quantityL", new ColumnValue(value));
		value = o.getPieceQuantityL();
 		values.put("pieceQuantityL", new ColumnValue(value));
		
		value = o.getDateIn();
 		values.put("dateIn", new ColumnValue(value));
		value = o.getDateOut();
 		values.put("dateOut", new ColumnValue(value));
		
		value = o.getOrderSize();
 		values.put("orderSize", new ColumnValue(value));
		value = o.getOrderWeight();
 		values.put("orderWeight", new ColumnValue(value));
		value = o.getManufacturer();
 		values.put("manufacturer", new ColumnValue(value));
		value = o.getLicenseValidDate();
 		values.put("licenseValidDate", new ColumnValue(value));
		
 		
		value = o.getComments();
 		values.put("comments", new ColumnValue(value));

		value = o.getcUsercode();
 		values.put("cUsercode", new ColumnValue(value));
		value = o.getcUsername();
 		values.put("cUsername", new ColumnValue(value));
		value = o.getcDatetime();
 		values.put("cDatetime", new ColumnValue(value));
		value = o.gettUsercode();
 		values.put("tUsercode", new ColumnValue(value));
		value = o.gettUsername();
 		values.put("tUsername", new ColumnValue(value));
		value = o.gettDatetime();
 		values.put("tDatetime", new ColumnValue(value));
		value = o.geteUsercode();
 		values.put("eUsercode", new ColumnValue(value));
		value = o.geteUsername();
 		values.put("eUsername", new ColumnValue(value));
		value = o.geteDatetime();
 		values.put("eDatetime", new ColumnValue(value));

		value = o.getsCreatorFID();
 		values.put("sCreatorFID", new ColumnValue(value));

		value = o.getUserId();
 		values.put("userId", new ColumnValue(value));
		value = o.getEnterpriseNo();
 		values.put("enterpriseNo", new ColumnValue(value));
		value = o.getEnterpriseName();
 		values.put("enterpriseName", new ColumnValue(value));

		value = o.getVersion();
 		values.put("version", new ColumnValue(value));
		
		Row row = new Row(values,RowState.NONE);
		return row;
	}
	
	public FileItem rowToObject(Row row){
		FileItem obj = new FileItem();
		obj.setfID(row.getString("fID"));
	    
		obj.setSystemCode(row.getString("systemCode"));			
		obj.setBillType(row.getString("billType"));
		obj.setBillTypeName(row.getString("billTypeName"));
		obj.setOrderDate(row.getDate("orderDate"));
		obj.setState(row.getString("state"));
		obj.setStatus(row.getString("status"));

		obj.setGroupID(row.getString("groupID"));
		obj.setGroupCode(row.getString("groupCode"));
		obj.setGroupName(row.getString("groupName"));
		obj.setGroupFullName(row.getString("groupFullName"));
		obj.setItemNo(row.getString("itemNo"));
//		obj.setItemDescribe(row.getString("itemDescribe"));
		obj.setRationSize(row.getString("rationSize"));
		
		obj.setItemName(row.getString("itemName"));
		obj.setClassCode(row.getString("classCode"));
		obj.setClassLabel(row.getString("classLabel"));
		obj.setItemProperty(row.getString("itemProperty"));
		obj.setOrgID(row.getString("orgID"));
		obj.setOrgFName(row.getString("orgFName"));

		obj.setUnitCode(row.getString("unitCode"));
		obj.setUnitName(row.getString("unitName"));
		obj.setProcess(row.getString("process"));
		obj.setProcessLabel(row.getString("processLabel"));
		obj.setCostingType(row.getInteger("costingType"));
		obj.setQualityType(row.getInteger("qualityType"));//进货费用(分摊)
		obj.setQualityTypeLabel(row.getString("qualityTypeLabel"));//进货费用(分摊)
		obj.setQualityPeriod(row.getInteger("qualityPeriod"));

		obj.setStoreNo(row.getString("storeNo"));
		obj.setBatchNo(row.getString("batchNo"));
		obj.setPlanType(row.getString("planType"));
		
		obj.setForSale(row.getString("forSale"));
		obj.setForUsed(row.getString("forUsed"));
//		obj.setOtemNo(row.getString("otemNo"));
//		obj.setOtemDescribe(row.getString("otemDescribe"));

		obj.setItemWeight(row.getDecimal("itemWeight"));
		obj.setItemSize(row.getString("itemSize"));
		obj.setImages(row.getString("images"));
		
		obj.setStorageNo(row.getString("storageNo"));
		obj.setStorageName(row.getString("storageName"));
		obj.setStorageType(row.getString("storageType"));
		obj.setStorageTypeLabel(row.getString("storageTypeLabel"));
		obj.setFloorNo(row.getString("floorNo"));

		obj.setSaxType(row.getInteger("saxType"));
		obj.setSaxTypeLabel(row.getString("saxTypeLabel"));
		obj.setSaxRate(row.getDecimal("saxRate"));
		obj.setSalePrice(row.getDecimal("salePrice"));

		obj.setTaxType(row.getInteger("taxType"));
		obj.setTaxTypeLabel(row.getString("taxTypeLabel"));
		obj.setTaxRate(row.getDecimal("taxRate"));
		obj.setItemPrice(row.getDecimal("itemPrice"));

	    obj.setAbcGrade(row.getString("abcGrade"));
		
		obj.setProviderNo(row.getString("providerNo"));
		obj.setShortName(row.getString("shortName"));
		obj.setProviderName(row.getString("providerName"));
		obj.setWorkcenterNo(row.getString("workcenterNo"));
		obj.setWorkcenterName(row.getString("workcenterName"));
		obj.setWorkcenterLName(row.getString("workcenterLName"));
		
		obj.setHumanHour(row.getDecimal("workingHourPlan"));
		obj.setMachineHour(row.getDecimal("machineHourPlan"));
		obj.setRoutingNo(row.getString("routingNo"));
		obj.setRoutingItemNo(row.getString("routingItemNo"));
	
		obj.setLevelCode(row.getInteger("levelCode"));
		obj.setMaterialAmountPer(row.getDecimal("materialAmountPer"));
		obj.setHumanAmountPer(row.getDecimal("workingAmountPer"));
		obj.setManufactAmountPer(row.getDecimal("manufactAmountPer"));
		obj.setProcessAmountPer(row.getDecimal("processAmountPer"));
		obj.setCostingAmountPer(row.getDecimal("costingAmountPer"));
		
		obj.setMaterialAmount(row.getDecimal("materialAmount"));
		obj.setHumanAmount(row.getDecimal("workingAmount"));
		obj.setManufactAmount(row.getDecimal("manufactAmount"));
		obj.setProcessAmount(row.getDecimal("processAmount"));
		obj.setCostingAmount(row.getDecimal("costingAmount"));
		
		obj.setValidDays(row.getInteger("validDays"));
		obj.setCheckoutAgainDays(row.getInteger("checkoutAgainDays"));
		obj.setHumanPrice(row.getDecimal("humanPrice"));
		obj.setQuantityL(row.getDecimal("quantityL"));
		obj.setPieceQuantityL(row.getDecimal("pieceQuantityL"));
	    
		obj.setDateIn(row.getDate("dateIn"));
		obj.setDateOut(row.getDate("dateOut"));

		obj.setProductNo(row.getString("productNo"));
		obj.setProjectNo(row.getString("projectNo"));
		
		obj.setOrderSize(row.getString("orderSize"));
		obj.setOrderWeight(row.getDecimal("orderWeight"));
		obj.setManufacturer(row.getString("manufacturer"));
		obj.setLicenseValidDate(row.getDate("licenseValidDate"));
		
		obj.setComments(row.getString("comments"));

		obj.setcUsercode(row.getString("cUsercode"));
		obj.setcUsername(row.getString("cUsername"));
		obj.setcDatetime(row.getDateTime("cDatetime"));
		obj.settUsercode(row.getString("tUsercode"));
		obj.settUsername(row.getString("tUsername"));
		obj.settDatetime(row.getDateTime("tDatetime"));
		obj.seteUsercode(row.getString("eUsercode"));
		obj.seteUsername(row.getString("eUsername"));
		obj.seteDatetime(row.getDateTime("eDatetime"));
		
		obj.setsCreatorFID(row.getString("sCreatorFID"));
		
		obj.setUserId(row.getString("userId"));

		obj.setEnterpriseNo(row.getString("enterpriseNo"));
		obj.setEnterpriseName(row.getString("enterpriseName"));
		
		obj.setVersion(row.getInteger("version"));
		
		obj.setRowState(row.getState());

		return obj;
	}
*/	

	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException {
		// TODO Auto-generated method stub
		
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject data = new JSONObject();
		data.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		List<String> idsNew = new ArrayList<String>();
		List<String> idsDel = new ArrayList<String>();
				
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
//			System.out.println("FileItem.save.javaObject-->"+javaObject);
			FileItem obj = JSON.toJavaObject(javaObject, FileItem.class);
//			System.out.println(obj.getRowState());
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
				idsNew.add(obj.getfID());
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
				idsDel.add(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				FileItem objNew = dao.update(obj);
				//返回+1后的version到前台BizData中进行刷新，使得前台的version与后台的一致。
				///////////////////////////////////////////////////////////////////////
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
				//////////////////////////////////////////////////////////////////////
			}
		}
		
		data.put("rows", rows);
		data.put("idsNew", idsNew);
		data.put("idsDel", idsDel);
		
		return data;
	}

	
	@Transactional
	@Override
	public JSONObject saveDetail(JSONObject object) throws ParseException {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject json = new JSONObject();
		json.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			StorageItem obj = JSON.toJavaObject(javaObject, StorageItem.class);
			if(RowState.NEW.equals(obj.getRowState())){
				detailDao.insert(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				detailDao.delete(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				StorageItem objNew = detailDao.update(obj);
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
			}
		}
		
		json.put("rows", rows);
		
		return json;
	}

	
	///////////////////////业务功能///////////////////////////////////////
	@Override
	public String getMaxSortNoPlus(String enterpriseNo) {
		return dao.getMaxSortNoPlus(enterpriseNo);
	}
	
	
	
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#getByName(java.lang.String, java.lang.String, java.lang.String)
	 */
	/*
	@Override
	public FileItem getByName(String itemName, String enterpriseNo) {
		return dao.getByName(itemName, enterpriseNo);
	}
	*/
	
	//初始化物料档案中的低阶码
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#initItemLowLevel(int)
	 */
	@Transactional
	@Override
	public int initItemLowLevel(String levelCode){
		List<FileItem> fis = dao.getAll();
		for(FileItem fi : fis){
			fi.setLevelCode(levelCode);
			dao.update(fi);
		}
		return 0;
	}
	
	//更新标准成本（根据BOM表计算得出）
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#updateCostingAmount(java.lang.String, java.math.BigDecimal, java.math.BigDecimal, java.math.BigDecimal, java.math.BigDecimal, java.math.BigDecimal, java.lang.String)
	 */
	@Transactional
	@Override
	public int updateCostingStandard(			
			String itemID
			,BigDecimal materialAmountPer
			,BigDecimal workingAmountPer
			,BigDecimal manufactAmountPer
			,BigDecimal processAmountPer
			,String enterpriseNo
			) {

		FileItem fi = dao.getByID(itemID);
		if(fi==null){
			return -1;
		}

		fi.setMaterialStandardPer(materialAmountPer);
		fi.setWorkingStandardPer(workingAmountPer);
		fi.setManufactStandardPer(manufactAmountPer);
		fi.setProcessStandardPer(processAmountPer);
			
		dao.update(fi);

		return 0;
	}
	
	@Transactional
	@Override
	public int updateStorage(String itemID ,String storageID) {

		FileItem fi = dao.getByID(itemID);
		if(fi==null){
			return -1;
		}

		fi.setStorageID(storageID);
			
		dao.update(fi);
		return 0;
	}
	
	//更新低阶码
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#updateLevelCode(com.iune.erp.inventory.FileItem, int)
	 */
	@Transactional
	@Override
	public int updateLevelCode(FileItem fi, String levelCode) {
		
		fi.setLevelCode(levelCode);
		dao.update(fi);

		return 0;
	}
	


	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IFileItemService#toMap(com.iune.erp.inventory.FileItem)
	 */
	
	@Override
	public void beforeInsert(FileItem obj) {
		if(obj.getItemNo()==null){
			//资产编号为null，产生编号
			String billType = obj.getBillType();
			String enterpriseNo = obj.getEnterpriseNo();
			String itemNo = settingService.getMaxCode(billType, enterpriseNo);
			obj.setItemNo(itemNo);
			
		}else{
			//判断是否为空格
			String itemNo = obj.getItemNo().trim();
			if("".equals(itemNo)){
				//资产编号为""，产生编号
				String billType = obj.getBillType();
				String enterpriseNo = obj.getEnterpriseNo();
				itemNo = settingService.getMaxCode(billType, enterpriseNo);
				obj.setItemNo(itemNo);
				
			}else{
				//去掉空格后赋值
				obj.setItemNo(itemNo);
			}
		}
	}
	
	@Override
	public void afterInsert(FileItem obj) {
		
	}

	@Override
	public void beforeDelete(String fID) {
//		System.out.println(fID);
		//删除sku
		/*
		List<FileItem> skus = dao.getSKUList(fID);
		for(FileItem sku:skus){
			dao.delete(sku.getfID());
		}
		*/
//		dao.deleteSKU(fID);
	}

	//更新预占库存数量
	@Transactional
	@Override
	public FileItem updateQuantityFrozen(
			String itemID
			, BigDecimal itemQuantityFrozen
			, BigDecimal pieceQuantityFrozen
			) {
		
		FileItem si = dao.getByID(itemID);
		
		si.setItemQuantityFrozen(si.getItemQuantityFrozen().add(itemQuantityFrozen));
		si.setPieceQuantityFrozen(si.getPieceQuantityFrozen().add(pieceQuantityFrozen));
		
		try {
			dao.update(si);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return si;
	}

	//入库登记
	/* 
	 */
	@Transactional
	@Override
	public FileItem storeRegister(
			String itemID
			, BigDecimal itemQuantity
			, BigDecimal costingAmount
			, BigDecimal pieceQuantity
			) {
		
		FileItem fileItem = dao.getByID(itemID);
		
		//首先判断是否存在记录，如果不存在就创建
		if (fileItem==null) {
			//不存在，报错
			System.out.println("物料档案不存在！");
			return null;
		}

		//登记
		
		fileItem.setItemQuantityL(fileItem.getItemQuantityL().add(itemQuantity));
		fileItem.setPieceQuantityL(fileItem.getPieceQuantityL().add(pieceQuantity));
		//金额
		fileItem.setCostingAmount(fileItem.getCostingAmount().add(costingAmount));
		
		fileItem.setDateIn(Utils.getCurrentDate());
		
//		try {
//			dao.update(fileItem);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return fileItem;
		
		return dao.update(fileItem);
	}


	//出库登记
	/* 
	 */
	@Transactional
	@Override
	public FileItem pickRegister(
			String itemID
			, BigDecimal itemQuantity
			, BigDecimal costingAmount
			, BigDecimal pieceQuantity
			, int frozenFlag
			) {
		
		FileItem fileItem = dao.getByID(itemID);
		
		//首先判断是否存在记录，如果不存在就创建
		if (fileItem==null) {
			//不存在，报错
			System.out.println("物料档案不存在！");
			return null;
		}
		
		//处理单位成本数据
		//出库（库存数量减少不影响单位成本数据，我们没有存储成本，所以不用处理）
		//登记
		fileItem.setItemQuantityL(fileItem.getItemQuantityL().subtract(itemQuantity));
		fileItem.setPieceQuantityL(fileItem.getPieceQuantityL().subtract(pieceQuantity));
		//金额
		fileItem.setCostingAmount(fileItem.getCostingAmount().subtract(costingAmount));
		
		fileItem.setDateOut(Utils.getCurrentDate());
		
		//减去客户订单预留数量
		if(frozenFlag==1) {
			fileItem.setItemQuantityFrozen(fileItem.getItemQuantityFrozen().subtract(itemQuantity));
			fileItem.setPieceQuantityFrozen(fileItem.getPieceQuantityFrozen().subtract(pieceQuantity));
		}

//		try {
//			dao.update(fileItem);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return fileItem;
		
		return dao.update(fileItem);
	}
	
	@Override
	public FileItem packing(
			String billType
			,String billTypeName
			,String cUsercode//=com.justep.system.context.ContextHelper.getOperator().getCode();
			,String cUsername//=com.justep.system.context.ContextHelper.getOperator().getName();
			,String userId //= com.justep.system.context.ContextHelper.getOperator().getID();
			,String enterpriseNo //= this.getEnterpriseNo();
			,String enterpriseName //= this.getEnterpriseName();
			){
		
		//SysInfo中记录的ID
		String APPID = "55f3d52b6ee954e7e2f2ced136bff58a";
		
		FileItem obj = new FileItem();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		obj.setBillType(billType);
		obj.setBillTypeName(billTypeName);
		obj.setSystemCode(APPID);//APPID
		obj.setState("active");
		obj.setStatus("open");
		obj.setOrderDate(Utils.getCurrentDate());
		
		obj.setProcess("P");
		obj.setProcessLabel("P.采购件");
		
		obj.setStockFlag(1);
		
//		obj.setGroupID(fID);
		obj.setBatchNo("********************");
		obj.setStoreNo("********************");
		obj.setForSale("Y");
		obj.setForUsed("N");
		obj.setMpsFlag(0);
		
		
//		obj.setItemAmount(BigDecimal.ZERO);
//		obj.setOrderAmount(BigDecimal.ZERO);
//		obj.setOrderAmountOld(BigDecimal.ZERO);
//		obj.setOrderAmountTax(BigDecimal.ZERO);
//		obj.setOrderAmountTotal(BigDecimal.ZERO);
//		obj.setAccountAmountOld(BigDecimal.ZERO);
//		obj.setAccountAmountTax(BigDecimal.ZERO);
//		obj.setAccountAmountTotal(BigDecimal.ZERO);
//		obj.setOrderAmountCleared(BigDecimal.ZERO);
//		obj.setAccountAmountCleared(BigDecimal.ZERO);
		
//		obj.setEmployeeNo(null);
//		obj.setEmployeeName(null);
		
//		obj.setComments("来自商城");
		
		obj.setcUsercode(cUsercode);
		obj.setcUsername(cUsername);
		obj.setcDatetime(Utils.getCurrentDateTime());
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setVersion(0);
		
		
		return obj;
	}


	@Transactional
	@Override
	public FileItem insert(String itemNo, String itemName, String itemProperty, String unitName, String cUsercode, String cUsername, String userId, String enterpriseNo, String enterpriseName) {
		
		String billType = "ITEM";
		String billTypeName = "物料档案";
		
		FileItem fileItem = this.packing(billType, billTypeName, cUsercode, cUsername, userId, enterpriseNo, enterpriseName);
		fileItem.setItemNo(itemNo);
		fileItem.setItemName(itemName);
		fileItem.setItemProperty(itemProperty);
		fileItem.setUnitName(unitName);
		fileItem.setBarcode(itemNo);
		
//		fileItem.setNodeKind("nkLeaf");
//		fileItem.setNodeLevel(1);
		
		dao.insert(fileItem);
		return fileItem;
	}

	
	/*
	 * 唯一性检查
	 * 返回值：通过检查（唯一），true；否则返回false
	 * 为saveData函数服务，做为保存前的数据唯一性验证
	 */
	@Override
	public JSONObject validData(JSONObject param) {
		JSONObject row = param.getJSONObject("row");
		//System.out.println("validData.param.row-->>"+row);
		
		String enterpriseNo = row.getJSONObject("enterpriseNo").getString("value");
		//String rowState = row.getJSONObject("userdata").getString("recordState");
		JSONObject userdata = row.getJSONObject("userdata");
		Object rowState = userdata.get("recordState");
		//log.info("rowState-->>"+rowState);
		
		int invalid = 0;
		
		//判断是否录入数据已经存在
		//itemNo
		String itemNo = row.getJSONObject("itemNo").getString("value");
		FileItem obj = dao.getByNo(itemNo, enterpriseNo);
		if(obj==null) {
			//不存在
			row.getJSONObject("itemNo").put("invalid", 0);
			row.getJSONObject("itemNo").put("invalidMsg", "不存在，数据有效。");
		}else {
			//已经存在
			//首先判断是否是新增，否则就是修改
			if(RowState.NEW.equals(rowState)){
				//新增
				row.getJSONObject("itemNo").put("invalid", 1);
				row.getJSONObject("itemNo").put("invalidMsg", "编码已经存在！");
				invalid++;
			}else {
				//修改
				//判是否为自身
				String fID = row.getJSONObject("fID").getString("value");
				//log.info("fID-->>"+fID);
				if(obj.getfID().equals(fID)) {
					//是
					row.getJSONObject("itemNo").put("invalid", 0);
					row.getJSONObject("itemNo").put("invalidMsg", "不存在，数据有效。");
				}else {
					//否
					row.getJSONObject("itemNo").put("invalid", 1);
					row.getJSONObject("itemNo").put("invalidMsg", "编码已经存在！");
					invalid++;
				}
			}
			
		}
		
		//名称
		String itemName = row.getJSONObject("itemName").getString("value");
		String itemProperty = row.getJSONObject("itemProperty").getString("value");
		FileItem obj1 = dao.getByName(itemName, itemProperty, enterpriseNo);
		if(obj1==null) {
			//不存在
			row.getJSONObject("itemName").put("invalid", 0);
			row.getJSONObject("itemName").put("invalidMsg", "不存在，数据有效。");
			row.getJSONObject("itemProperty").put("invalid", 0);
			row.getJSONObject("itemProperty").put("invalidMsg", "不存在，数据有效。");
		}else {
			//已经存在
			//首先判断是否是新增，否则就是修改
			if(RowState.NEW.equals(rowState)){
				//新增
				row.getJSONObject("itemName").put("invalid", 1);
				row.getJSONObject("itemName").put("invalidMsg", "名称/规格已经存在！");
				row.getJSONObject("itemProperty").put("invalid", 1);
				row.getJSONObject("itemProperty").put("invalidMsg", "名称/规格已经存在！");
				invalid++;
			}else {
				//修改
				//判是否为自身
				String fID = row.getJSONObject("fID").getString("value");
				//log.info("fID-->>"+fID);
				if(obj1.getfID().equals(fID)) {
					//是
					row.getJSONObject("itemName").put("invalid", 0);
					row.getJSONObject("itemName").put("invalidMsg", "不存在，数据有效。");
					row.getJSONObject("itemProperty").put("invalid", 0);
					row.getJSONObject("itemProperty").put("invalidMsg", "不存在，数据有效。");
				}else {
					//否
					row.getJSONObject("itemName").put("invalid", 1);
					row.getJSONObject("itemName").put("invalidMsg", "名称/规格已经存在！");
					row.getJSONObject("itemProperty").put("invalid", 1);
					row.getJSONObject("itemProperty").put("invalidMsg", "名称/规格已经存在！");
					invalid++;
				}
			}
			
		}
		
		//货号
		String barcode = row.getJSONObject("barcode").getString("value");
		FileItem obj2 = dao.getByBarcode(barcode, enterpriseNo);
		if(obj2==null) {
			//不存在
			row.getJSONObject("barcode").put("invalid", 0);
			row.getJSONObject("barcode").put("invalidMsg", "不存在，数据有效。");
		}else {
			//已经存在
			//首先判断是否是新增，否则就是修改
			if(RowState.NEW.equals(rowState)){
				//新增
				row.getJSONObject("barcode").put("invalid", 1);
				row.getJSONObject("barcode").put("invalidMsg", "货号/条码已经存在！");
				invalid++;
			}else {
				//修改
				//判是否为自身
				String fID = row.getJSONObject("fID").getString("value");
				//log.info("fID-->>"+fID);
				if(obj2.getfID().equals(fID)) {
					//是
					row.getJSONObject("barcode").put("invalid", 0);
					row.getJSONObject("barcode").put("invalidMsg", "不存在，数据有效。");
				}else {
					//否
					row.getJSONObject("barcode").put("invalid", 1);
					row.getJSONObject("barcode").put("invalidMsg", "货号/条码已经存在！");
					invalid++;
				}
			}
			
		}
		
		row.getJSONObject("userdata").put("invalid", invalid);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", row);

		return json;
	}
	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		//System.out.println("fileFactoryCreate.param-->>"+param.toJSONString());
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			String enterpriseNo = dao.getByID(id).getEnterpriseNo();
			//这里可以增加是否可删除的判断
			//首先删除子表
			//物料仓库档案，如果存在，则不允许删除
			
			List<StorageItem> sods = detailDao.getByItemID(id,enterpriseNo);
			if(sods.size()>0) {
				JSONObject json = new JSONObject();
				json.put("code", -2);
				json.put("msg", "存在物料仓库档案，无法删除。");
				return json;
			}
			
			
			//100、验证SKU档案
			List<FileItem> skus = dao.getSKUList(id);
			if(skus.size()>0) {
				//存在SKU档案，需要将SKU档案删除后才能删除
				JSONObject json = new JSONObject();
				json.put("code", -1);
				json.put("msg", "存在SKU物料档案，无法删除。");
				return json;
			}
			
			//还有验证物料属性
			//物料BOM
			//产品结构树
			//。。。。。。
			//。。。。。。
			
			//删除之前：物料规格列表和物料仓库档案必须已经不存在
			//否则不允许删除物料档案
			dao.delete(id);
		}
		
		
		//删除之前：物料规格列表和物料仓库档案必须已经不存在
		//否则不允许删除物料档案
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			dao.delete(id);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}

	/*
	在@Transaction注解中定义noRollbackFor和RollbackFor指定某种异常是否回滚。 
	@Transactional(noRollbackFor=RuntimeException.class) 
	@Transactional(RollbackFor=Exception.class) 
	*/
	@Transactional
	@Override
	public JSONObject saveData(JSONObject param) {
		//Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚。 
		//如果一个方法抛出Exception或者Checked异常，Spring事务管理默认不进行回滚。 
		// JSON转换Table
		//System.out.println(object);
		JSONObject data;
		try {
			//保存主表
			data = this.save(param);
			
			//保存从表
			JSONArray slaves = param.getJSONArray("slaves");
			if(slaves.size()>0) {
				JSONObject slaveParam = slaves.getJSONObject(0);
				JSONObject slaveData = this.saveDetail(slaveParam);
				JSONArray slaveDatas = new JSONArray();
				slaveDatas.add(slaveData);
				data.put("slaves", slaveDatas);
			}
					
			//返回
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			log.info("开始打印ParseException");
			e.printStackTrace();
			log.info("e.getMessage()-->>"+e.getMessage());
			log.info("完成打印ParseException");
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	/* (non-Javadoc)
	 * @see com.iune.erp.baseinfo.aaa#queryJDBC(com.alibaba.fastjson.JSONObject)
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	@Override
	public JSONObject queryData(JSONObject param){
		//在此层面（ServiceImpl）统一处理异常，此层面直接被controller调用，面对BizData
		
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}

	//新增子表
	@Override
	public JSONObject newDataDetail(JSONObject data) {
		return detailDao.create(data);
	}
	
	//查询子表
	@Override
	public JSONObject queryDataDetail(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = detailDao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}

	
}
